package com.flick.aop;

import com.flick.annotation.AutoResult;
import com.flick.annotation.NotAutoResult;
import com.flick.common.CommonPage;
import com.flick.common.Result;
import org.springframework.core.MethodParameter;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;

@RestControllerAdvice
public class ResultHandler implements ResponseBodyAdvice<Object>{

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        if(returnType.getGenericParameterType().getTypeName().equals(Result.class.getTypeName())) return false;
        Method method = returnType.getMethod();
        AutoResult methodAnnotation = method.getAnnotation(AutoResult.class);
        NotAutoResult notAutoResult = method.getAnnotation(NotAutoResult.class);
        AutoResult classAnnotation = method.getDeclaringClass().getAnnotation(AutoResult.class);
        if(notAutoResult==null && (methodAnnotation != null || classAnnotation != null)) {
        // 只处理含有AutoResult注解的方法
            return true;
        }
        return false;
    }

    @Override
    public Object beforeBodyWrite(Object obj, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {
        // 修改返回值类型
        Result result = new Result();
        result.setCode("200");
        result.setMsg("success");
        result.setData(obj);
        if(obj.getClass().isArray() || obj instanceof Collection || obj instanceof Map) result.setDataType(2);
        else if(obj instanceof Page){
            result.setDataType(3);
            Page page = (Page)obj;
            CommonPage commonPage = new CommonPage();
            commonPage.setPageNum(page.getNumber() + 1);
            commonPage.setPageSize(page.getSize());
            commonPage.setTotal(page.getTotalElements());
            commonPage.setMaxPage(page.getTotalPages());
            commonPage.setRecords(page.getNumberOfElements());
            commonPage.setObj(page.getContent());
            result.setData(commonPage);
        }else result.setDataType(1);
        return result;
    }

}
